package org.ragdollcat.first.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.ragdollcat.first.manager.auth.StpKit;
import org.ragdollcat.first.common.BaseResponse;
import org.ragdollcat.first.common.ResultUtils;
import org.ragdollcat.first.common.ValidationUtil;
import org.ragdollcat.first.constants.UserConstant;
import org.ragdollcat.first.exception.ErrorCode;
import org.ragdollcat.first.exception.ThrowUtils;
import org.ragdollcat.first.model.dto.user.UserQueryRequest;
import org.ragdollcat.first.model.entity.User;
import org.ragdollcat.first.model.enums.UserRoleEnum;
import org.ragdollcat.first.model.vo.LoginUserVO;
import org.ragdollcat.first.model.vo.UserVO;
import org.ragdollcat.first.service.UserService;
import org.ragdollcat.first.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 86158
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2025-08-11 21:38:54
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    public UserServiceImpl(StpKit stpKit) {
    }

    /**
     * 用户注册
     * @param account
     * @param password
     * @param rePassword
     * @return
     */
    @Override
    public BaseResponse<?> userRegister(String account, String password, String rePassword) {
        //1.参数校验
        ThrowUtils.throwIf(StrUtil.hasBlank(account,password,rePassword), ErrorCode.PARAMS_ERROR,"请求参数不能为空，请检查");
        ThrowUtils.throwIf(!ValidationUtil.isValidUsername(account),ErrorCode.OPERATION_ERROR,"用户名：4-20位（中文、英文）");
        ThrowUtils.throwIf(!ValidationUtil.isValidPassword(password),ErrorCode.OPERATION_ERROR,"密码：8-20位（必须包含大小写字母和数字）");
        //2.判断用户名在用户表中是否存在
        User user = getOne(new QueryWrapper<User>().eq("userAccount", account));
        ThrowUtils.throwIf(ObjectUtil.isNotEmpty(user),ErrorCode.OPERATION_ERROR,"该用户已注册，请进行登录操作");
        //3.判断两次的密码是否一致
        ThrowUtils.throwIf(!password.equals(rePassword),ErrorCode.OPERATION_ERROR,"两次输入的密码不一致，请检查！");
        //4.密码加密
        String encryptPassword = passwordEncryption(password);
        //5.保存用户
        User saveUser = new User();
        saveUser.setUserName("褪色者");
        saveUser.setUserPassword(encryptPassword);
        saveUser.setUserAccount(account);
        saveUser.setUserRole(UserRoleEnum.USER.getValue());
        ThrowUtils.throwIf(!save(saveUser),ErrorCode.SYSTEM_ERROR,"系统异常，请联系管理员");;
        return ResultUtils.success(null);
    }

    /**
     * 用户登录
     *
     * @param account
     * @param password
     * @param httpServerRequest
     * @return
     */
    @Override
    public BaseResponse<LoginUserVO> userLogin(String account, String password, HttpServletRequest httpServerRequest) {
        //参数校验
        ThrowUtils.throwIf(StrUtil.hasBlank(account,password),ErrorCode.PARAMS_ERROR,"用户名或密码不能为空");
        //判断用户是否存在
        User user = getOne(new QueryWrapper<User>().eq("userAccount", account));
        ThrowUtils.throwIf(ObjectUtils.isEmpty(user),ErrorCode.NOT_FOUND_ERROR,"用户不存在！");
        //判断用户的状态
        ThrowUtils.throwIf(user.getIsDelete() == 1 ,ErrorCode.OPERATION_ERROR,"用户状态异常！");
        //校验密码（加密）
        String encryptPassword = passwordEncryption(password);
        ThrowUtils.throwIf(!encryptPassword.equals(user.getUserPassword()),ErrorCode.OPERATION_ERROR,"用户名或密码错误！");
        //存入session
        httpServerRequest.getSession().setAttribute(UserConstant.USER_LOGIN_STATE,user);
        //适配团队空间鉴权，同时向satoken中存一份
        StpKit.SPACE.login(user.getId());
        StpKit.SPACE.getSession().set(UserConstant.USER_LOGIN_STATE,user);
        return ResultUtils.success(this.castUserToLoginUserVO(user));
    }

    @Override
    public LoginUserVO castUserToLoginUserVO(User user) {
        if (ObjectUtils.isEmpty(user)){
            return null;
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(user,loginUserVO);
        return loginUserVO;
    }

    /**
     * 获取当前登录用户
     *
     * @param httpServerRequest
     * @return
     */
    @Override
    public User getLoginUser(HttpServletRequest httpServerRequest) {
        User user = (User) httpServerRequest.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        ThrowUtils.throwIf(ObjectUtils.isEmpty(user),ErrorCode.NOT_LOGIN_ERROR,"用户未登录！");
        //判断用户的状态
        ThrowUtils.throwIf(user.getIsDelete() == 1 ,ErrorCode.OPERATION_ERROR,"用户状态异常！");
        //如果需要保证数据强一致性，就要再次查询数据库
        Long id = user.getId();
        User userCurrent = getById(id);
        ThrowUtils.throwIf(ObjectUtils.isEmpty(userCurrent) ,ErrorCode.NOT_FOUND_ERROR,"用户不存在！");
        //再次判断用户的状态
        ThrowUtils.throwIf(userCurrent.getIsDelete() == 1 ,ErrorCode.OPERATION_ERROR,"用户状态异常！");
        return userCurrent;
    }

    /**
     * 退出登录
     *
     * @param request
     */
    @Override
    public void userLoginout(HttpServletRequest request) {
        request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
        //从satoken中移除
        StpKit.SPACE.logout();
    }

    /**
     * 密码加密
     *
     * @param password
     * @return
     */
    @Override
    public String passwordEncryption(String password) {
        final String slat = "秋风不至深山处";
        return DigestUtils.md5DigestAsHex((password + slat).getBytes());
    }

    @Override
    public UserVO castUserToUserVo(User user) {
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user,userVO);
        return userVO;
    }

    /**
     * 得到Mybatisplus 的用户查询条件
     *
     * @param userQueryRequest
     * @return
     */
    @Override
    public Wrapper<User> getUserQueryWrapper(UserQueryRequest userQueryRequest) {
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        Long id = userQueryRequest.getId();
        //用户名称
        String userName = userQueryRequest.getUserName();
        //用户账户
        String userAccount = userQueryRequest.getUserAccount();
        //用户简介
        String userProfile = userQueryRequest.getUserProfile();
        //用户角色
        String userRole = userQueryRequest.getUserRole();
        //排序字段
        String sortField = userQueryRequest.getSortField();
        //排序方式
        String sortOrder = userQueryRequest.getSortOrder();
        //根据ID和角色精确查询
        userQueryWrapper.eq(ObjectUtil.isNotEmpty(id),"id",id);
        userQueryWrapper.eq(ObjectUtil.isNotEmpty(userRole),"userRole",userRole);
        //其他条件模糊查询
        userQueryWrapper.like(ObjectUtil.isNotEmpty(userName),"userName",userName);
        userQueryWrapper.like(ObjectUtil.isNotEmpty(userAccount),"userAccount",userAccount);
        userQueryWrapper.like(ObjectUtil.isNotEmpty(userProfile),"userProfile",userProfile);
        //排序
        userQueryWrapper.orderBy(ObjectUtil.isNotEmpty(sortField),sortOrder.equals("ascend"),sortField);
        return userQueryWrapper;
    }

    @Override
    public List<UserVO> castUsersToUserVos(List<User> records) {
        if (CollUtil.isEmpty(records)){
            return null;
        }
        return records.stream().map(this::castUserToUserVo).collect(Collectors.toList());
    }

    @Override
    public boolean isAdmin(User user) {
        return user.getUserRole().equals(UserConstant.ADMIN_ROLE);
    }
}




